﻿using System;
using System.Collections.Specialized;
using System.Diagnostics;
using System.Net;
using System.Net.Security;
using System.Configuration;
using TimeMgr.ServerTimeWS;

namespace TimeMgr
{
    ///<summary>
    ///</summary>
    public class TimeMgr:ITimeMgr
    {
        private static ServerTime _ws;

        ///<summary>
        ///</summary>
        ///<returns></returns>
        ///<exception cref="Exception"></exception>
        internal static ServerTime ObtenerInstancia()
        {
            if (_ws == null)
            {
                _ws = new ServerTime();
                ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(ValidateServerCertificate);
                CredentialCache credential = new CredentialCache();
                _ws.Credentials = credential;
            }
            NameValueCollection appFile = ConfigurationManager.AppSettings;
            if (appFile.Get("URLServicioWebTime")!=null)
            {
                _ws.Url = appFile.Get("URLServicioWebTime");
            }
            else
            {
                throw new Exception("Falta la clave URLServicioWebTime en el archivo de configuración");
            }
            return _ws;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="url"></param>
        /// <param name="throwExceptions"></param>
        /// <param name="errorMessage"></param>
        /// <returns></returns>
        internal static bool ServiceExists(string url, bool throwExceptions, out string errorMessage)
        {
            try
            {
                errorMessage = string.Empty;

                // try accessing the web service directly via it's URL
                var request = WebRequest.Create(url) as HttpWebRequest;
                if (request != null)
                {
                    request.Timeout = 30000;

                    using (var response = request.GetResponse() as HttpWebResponse)
                    {
                        if (response != null)
                            if (response.StatusCode != HttpStatusCode.OK)
                                throw new Exception("Error al invocar el web service");
                    }
                }
            }
            catch (WebException ex)
            {
                // decompose 400- codes here if you like
                errorMessage = string.Format("Error testeando la conexion al web service en \"{0}\":\r\n{1}", url, ex);
                Trace.TraceError(errorMessage);
                if (throwExceptions)
                    throw new Exception(errorMessage, ex);
            }
            catch (Exception ex)
            {
                errorMessage = string.Format("Error testeando la conexion al web service en \"{0}\":\r\n{1}", url, ex);
                Trace.TraceError(errorMessage);
                if (throwExceptions)
                    throw new Exception(errorMessage, ex);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="certificate"></param>
        /// <param name="chain"></param>
        /// <param name="sslPolicyErrors"></param>
        /// <returns></returns>
        internal static Boolean ValidateServerCertificate(object sender, System.Security.Cryptography.X509Certificates.X509Certificate certificate, System.Security.Cryptography.X509Certificates.X509Chain chain, SslPolicyErrors sslPolicyErrors)
        {
            return true;
        }

        /// <summary>
        /// Obtiene la fecha actual del sistema
        /// </summary>
        /// <returns></returns>
        public DateTime ObtenerFecha()
        {
            NameValueCollection appFile = ConfigurationManager.AppSettings;
            try
            {
                string mensajeError;
                if (ServiceExists(appFile.Get("URLServicioWebTime"), true, out mensajeError))
                {
                    ObtenerInstancia();
                    string datetime = _ws.GetDateTime();
                    DateTime datetimeFormated;
                    Boolean exito = DateTime.TryParse(datetime, out datetimeFormated);
                    return exito ? datetimeFormated : DateTime.UtcNow;
                }
                return DateTime.UtcNow;
            }
            catch (Exception)
            {
                return DateTime.UtcNow;
            }

        }
    }
}